package com.util;

import com.alibaba.fastjson.JSONObject;
import com.domain.Issue;
import com.domain.IssueComment;
import com.domainUtil.ImgCheckResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mapper.helping.*;
import com.qiniu.common.QiniuException;
import com.service.IIssueCommentResponseGrandsonService;
import com.service.IIssueCommentService;
import com.service.IIssueService;
import com.service.ILabelService;
import com.service.living.OfficialMessageService;
import com.service.living.SendDingMessageService;
import living.com.domain.AccessToken;
import living.com.domain.ContentCheckResponse;
import living.com.domain.DingMessage;
import living.com.domain.OfficialMessageType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 微信处理器
 * </p>
 *
 * @author 大忽悠
 * @create 2022/2/10 21:10
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class WeiXinUtil {

    private static final RestTemplate restTemplate = new RestTemplate();

    /**
     * 下面两个属性是固定配置,用于获取access_token,如果有变动,再进行修改
     */
    public static final String APP_ID = "wxd7829080ef324961";
    public static final String SECRET = "9cc68d85867173a501332aa74acb7d70";

    private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type={grant_type}&appid={appid}&secret={secret}";

    private static final String TEXT_URL = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=";

    private static final String PIC_URL="https://api.weixin.qq.com/wxa/img_sec_check?access_token=";

    private static volatile String TOKEN;

    private static volatile long TOKEN_EXPIRE_TIME;

    private final IssueCommentResponseMapper issueCommentResponseMapper;
    private final IIssueService iIssueService;
    private final OfficialMessageService officialMessageService;
    private final ILabelService iLabelService;
    private final IIssueCommentService iIssueCommentService;
    private final IIssueCommentResponseGrandsonService iIssueCommentResponseGrandsonService;
    private final QiNiuYunUtils qiNiuYunUtils;
    /**
     * 微信检查文本内容是否合法
     * 异步校验
     * 文本内容,文本类型,文本id,发布者id,发布者openId
     */
    @Async("DhyExecutor")
    public void checkText(String content, WeiXinCheckTextType textType, int text_id, Integer publisherId, String openId)
            throws IOException {
        ContentCheckResponse contentCheckResponse = doGetWeiXinCheckTextRes(content, openId);
        //审核不通过
        if (!"pass".equals(contentCheckResponse.getResult().getSuggest())) {
            //消息格式
            StringBuilder stringBuilder=new StringBuilder();
            stringBuilder.append(publisherId+"号用户发布的"+text_id+"号");
            //删除指定文本消息
            logicDelText(text_id,textType,stringBuilder);
            stringBuilder.append("内容["+content+"]审核未通过");
            //发送钉钉消息
            SendDingMessageService.sendContentAuditMessage
                    (new DingMessage(stringBuilder.toString()));
            //给发布者发布官方消息
            officialMessageService.sendOfficialMessage("您的动态含有违规内容,已被管理员删除", null, publisherId, OfficialMessageType.PUNISH);
        }
    }


    /**
     * 微信检查图片内容是否合法
     * 异步校验
     * 图片url链接,文本类型,文本id,发布者id,发布者openId
     */
    @Async("DhyExecutor")
    public void checkImg(List<String> urls, WeiXinCheckTextType textType, int text_id, int publisherId, String openId)
            throws IOException {
        //判断是否有图片需要进行审核
        if(urls==null||urls.size()==0)
        {
            return;
        }
        for (String url : urls) {
            ImgCheckResult imgCheckResult = doGetWeiXinCheckImgRes(url, openId);
            //审核不通过
            if (!imgCheckResult.getErrmsg().equals("ok")) {
                //消息格式
                StringBuilder stringBuilder=new StringBuilder();
                stringBuilder.append(publisherId+"号用户发布的"+text_id+"号");
                //删除当前文本关联的所有图片资源和视频资源
                delTextFiles(text_id,textType);
                //删除指定文本消息
                logicDelText(text_id,textType,stringBuilder);
                stringBuilder.append("图片审核未通过");
                //发送钉钉消息
                SendDingMessageService.sendContentAuditMessage
                        (new DingMessage(stringBuilder.toString()));
                //给发布者发布官方消息
                officialMessageService.sendOfficialMessage("您的动态含有违规内容,已被管理员删除", null, publisherId, OfficialMessageType.PUNISH);
                //一个图片审核失败,就退出审核
                break;
            }
        }
    }

    private void delTextFiles(int text_id, WeiXinCheckTextType textType) throws JsonProcessingException, QiniuException {
        //回答
        String imgs=null;
        String videos=null;
        if (textType.equals(WeiXinCheckTextType.FATHER_COMMENT)) {
            IssueComment issueComment = iIssueCommentService.getById(text_id);
            imgs = issueComment.getImgs();
            videos = issueComment.getVideos();
        }
        //问题
        else if (textType.equals(WeiXinCheckTextType.ISSUE_TITLE) || textType.equals(WeiXinCheckTextType.ISSUE_DETAILS)) {
            Issue issue = iIssueService.getById(text_id);
            imgs=issue.getImgs();
            videos=issue.getVideos();
        }
        commonFileDelOperations(imgs);
        commonFileDelOperations(videos);
    }

    private void commonFileDelOperations(String paths) throws QiniuException, JsonProcessingException {
            if(paths!=null&&!paths.equals("")&&!paths.equals("[]"))
            {
                qiNiuYunUtils.deleteFileJson(paths);
            }
    }



    /**
     * 删除文本---直接删除
     */
    @Deprecated
    private void delText(int text_id, WeiXinCheckTextType textType,StringBuilder stringBuilder) throws QiniuException, JsonProcessingException {
        if (textType.equals(WeiXinCheckTextType.FATHER_COMMENT)) {
            //删除父评论
            iIssueCommentService.delTargetComment (text_id);
            stringBuilder.append("父评论");
        } else if (textType.equals(WeiXinCheckTextType.SON_COMMENT)) {
            //子评论审核不通过
            issueCommentResponseMapper.deleteById(text_id);
            stringBuilder.append("子评论");
        } else if (textType.equals(WeiXinCheckTextType.ISSUE_TITLE) || textType.equals(WeiXinCheckTextType.ISSUE_DETAILS)) {
            //问题审核不通过
            iIssueService.delTargetQuestion(text_id);
            stringBuilder.append("问题");
        }else if(textType.equals(WeiXinCheckTextType.LABEL_CONTENT))
        {
            //标签内容审核失败
            iLabelService.delTargetLabel(text_id);
            stringBuilder.append("标签");
        }else if(textType.equals(WeiXinCheckTextType.GRANT_SON_COMMENT))
        {
            //孙子评论审核失败
            iIssueCommentResponseGrandsonService.logicDelById(text_id);
            stringBuilder.append("孙子评论");
        }
    }

    /**
     * 逻辑删除---隐式删除
     */
    private void logicDelText(int text_id, WeiXinCheckTextType textType,StringBuilder stringBuilder)
    {
        if (textType.equals(WeiXinCheckTextType.FATHER_COMMENT)) {
            //删除父评论
            iIssueCommentService.WeiXinDel(text_id);
            stringBuilder.append("父评论");
        } else if (textType.equals(WeiXinCheckTextType.SON_COMMENT)) {
            //子评论审核不通过
            issueCommentResponseMapper.logicDelById(text_id);
            stringBuilder.append("子评论");
        } else if (textType.equals(WeiXinCheckTextType.ISSUE_TITLE) || textType.equals(WeiXinCheckTextType.ISSUE_DETAILS)) {
            //问题审核不通过
            iIssueService.WeiXinDel(text_id);
            stringBuilder.append("问题");
        }else if(textType.equals(WeiXinCheckTextType.LABEL_CONTENT))
        {
            //标签内容审核失败
            iLabelService.delTargetLabel(text_id);
            stringBuilder.append("标签");
        }
    }

    /**
     * @return 返回access_token
     */
    private String getToken() {
        if (TOKEN == null || TOKEN_EXPIRE_TIME < System.currentTimeMillis()) {
            synchronized (this.getClass()) {
                if (TOKEN == null || TOKEN_EXPIRE_TIME < System.currentTimeMillis()) {
                    log.info("token 已过期,重新获取");
                    Map<String, String> data = new HashMap<>(8);
                    data.put("grant_type", "client_credential");
                    data.put("appid", APP_ID);
                    data.put("secret", SECRET);
                    ResponseEntity<AccessToken> entity = restTemplate.getForEntity(TOKEN_URL, AccessToken.class, data);
                    log.info("获取到的access_token为:" + entity.getBody());
                    if (entity.getBody() == null) {
                        throw new IllegalArgumentException("微信获取access_token异常");
                    }
                    TOKEN = entity.getBody().getAccess_token();
                    TOKEN_EXPIRE_TIME = System.currentTimeMillis() + 7000 * 1000;
                    return entity.getBody().getAccess_token();
                } else {
                    return TOKEN;
                }
            }
        } else {
            return TOKEN;
        }
    }


    /**
     * 获取微信文字审核结果,传入文本内容和对应的用户openId
     */
    private ContentCheckResponse doGetWeiXinCheckTextRes(String content, String openId) throws IOException {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Content-Type", "application/json;charset=UTF-8");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("content", content);
        jsonObject.put("version", "2");
        jsonObject.put("openid", openId);
        jsonObject.put("scene", "3");
        ContentCheckResponse contentCheckResponse = restTemplate.postForObject(TEXT_URL + getToken(), new HttpEntity<>(jsonObject, httpHeaders), ContentCheckResponse.class);
        log.info("微信文本审核结果为:" + contentCheckResponse);
        return contentCheckResponse;
    }


    /**
     * 获取微信图片审核的结果,传入公网可访问的图片url和对应的用户openId
     */
    private ImgCheckResult doGetWeiXinCheckImgRes(String url, String openId) throws IOException {
        byte[] bytes = qiNiuYunUtils.downLoadFile(url);
        return qiNiuYunUtils.uploadFile(bytes,PIC_URL + getToken());
    }



    /**
     * 微信检查的文本类型: 评论,问题,问题详情
     */
    public static enum WeiXinCheckTextType {
        FATHER_COMMENT(0), SON_COMMENT(1), ISSUE_TITLE(2), ISSUE_DETAILS(3),LABEL_CONTENT(4)
        ,GRANT_SON_COMMENT(5);
        WeiXinCheckTextType(int index)
        {
            this.index=index;
        }
        int index;
        public static WeiXinCheckTextType getTargetType(int type)
        {
            switch (type)
            {
                case 0: return FATHER_COMMENT;
                case 1: return SON_COMMENT;
                case  2: return ISSUE_TITLE;
                case 3: return ISSUE_DETAILS;
                case 4: return LABEL_CONTENT;
                case 5: return  GRANT_SON_COMMENT;
            }
            throw new IllegalArgumentException("WeiXinCheckTextType参数类型有误");
        }
    }
}

